/**
 * @param { string } path
 * @returns { Boolean }
 */
export function isExternal (path) {
    return /^(https?:|mailto:|tel:)/.test(path)
}

// 获取屏幕缩放比例
export function getRatio() {
    let ratio = 0, screen = window.screen
    let ua = navigator.userAgent.toLocaleLowerCase()

    if (window.devicePixelRatio !== undefined) {
        ratio = window.devicePixelRatio
    } else if (~ua.indexOf("msie")) {
        if (screen.deviceXDPI && screen.logicalXDPI) {
            ratio = screen.deviceXDPI / screen.logicalXDPI
        }
    } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
        ratio = window.outerWidth / window.innerWidth
    }

    if (ratio) {
        ratio = Math.round(ratio * 100)
    }

    return ratio
}

// 存储数据到 localstorage 中
export const setStorage = (key, value) => {
    localStorage.setItem(key, value)
}

// 删除 localstorage 中的数据
export const removeStorage = (key) => {
    localStorage.removeItem(key)
}

// 获取 localstorage 中的数据
export const getStorage = (key) => {
    let value = localStorage.getItem(key)

    if (!value) return

    return value
}

// 监听事件
export const addListener = (key, callback) => {
    window.addEventListener(key, callback)
}

// 移除事件的监听
export const removeListener = (key, handler) => {
    window.removeEventListener(key, handler)
}


// 下载文件，参数：res 文件流，newFileName 新文件名, isDownload 是否下载
export const download = (res, newFileName, isDownload=true) => {
    const link = document.createElement('a')

    try {
        // 如果后台返回的不是blob对象类别，先定义成blob对象格式
        let blob = new Blob([res], {
            type: 'application/vnd.ms-excel;charset=utf-8'
        })

        let fileName = new Date().getTime() + newFileName

        link.style.display = 'none'

        // 兼容不同浏览器的URL对象
        let url = window.URL.createObjectURL(blob)

        link.href = url
        link.download = fileName //下载的文件名称

		if (!isDownload) {
			return url
		}

        link.click()
        window.URL.revokeObjectURL(url) //  #URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL. 当你要已经用过了这个对象URL,然后要让浏览器知道这个URL已经不再需要指向对应的文件的时候,就需要调用这个方法.
    } catch (e) {
        console.log('下载的文件出错', e)
    }
}

// 查看大图（在浏览器上打开新窗口）
export const seeBigImg = (url) => {
    window.open(url, '_blank')
}

// 限制表单只能输入数字、小数
export const verifyFloat = (e) => {
    e.target.value = e.target.value.replace(/[^\d.]/g, '') // 清除“数字”和“.”以外的字符
    .replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的
    .replace(/^\./g, '') // 保证第一个为数字而不是.
    .replace('.', '$#$')
    .replace(/\./g, '')
    .replace('$#$', '.')
}

// 限制表单只能输入数字、小数(并且只能输入两位小数)
export const verifyFloatNum = (e) => {
    e.target.value = e.target.value.replace(/[^\d.]/g, '') // 清除“数字”和“.”以外的字符
    .replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的
    .replace(/^\./g, '') // 保证第一个为数字而不是.
    .replace('.', '$#$')
    .replace(/\./g, '')
    .replace('$#$', '.')
    .replace(/^()*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能输入两位小数
}

// 限制表单只能输入数字
export const verifyNumber = (e) => {
    return e.target.value.replace(/[^\d]/g, '')
}

// 校验手机号
export const checkPhoneNum = (e) => {
    // 匹配以 1 开头，第二位为 3-9 的数字，后面跟着 9 个数字的正则
    let reg = /^1[3-9]\d{9}$/g
    let value = e.target.value

    if (!value) {
        return ''
    }

    if (!reg.test(value)) {
        Utils.popUpMsg('warning', '手机号不合法', 1000)
        e.target.value = ''
    }
}

// 校验手机号和带区号的电话
export const checkPhoneNumber = (e) => {
    // 匹配以 1 开头，第二位为 3-9 的数字，后面跟着 9 个数字的正则，或者带区号的电话号码
    let reg = /^(1[3-9]\d{9}|0\d{2,3}-\d{7,8}(-\d{1,6})?)$/g
    let value = e.target.value

    if (!value) {
        return ''
    }

    if (!reg.test(value)) {
        Utils.popUpMsg('warning', '电话号码不合法', 1000)
        e.target.value = ''
		return false
    }
};


// 校验邮箱
export const checkEmail = (e) => {
    let reg = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+$)/
    let value = e.target.value

    if (!value) {
        return ''
    }

    if (!reg.test(value)) {
        Utils.popUpMsg('warning', '邮箱不合法', 1000)
        e.target.value = ''
    }
}

// 根据某个字段值匹配数组中的元素
// data：数组，val：要匹配的值
export const matchArrData = (data, val) => {
    for (let i = 0; i < data.length; i++) {
        if (data[i].name === val) {
            return data[i]
        }
        
        if (data[i].children) {
            let row = matchArrData(data[i].children, val)

            if (row) {
                return row
            }
        }
    }

    return null
}

// 数组去重
// data1、data2 数据集合
// field：用来区分数据的唯一值
export const uniqueArr = (data1, data2, field) => {
    data1.forEach(item => {
        data2.forEach((j, index) => {
            if (item.id === j.id) {
                data2.splice(index, 1)
            }
        })
    })

    let data = data1.concat(data2)

    return data
}

// 单个数组去重，id：根据这个字段去重
export const uniqueData = (data, field) => {
	let arr = data.reduce((prev, curr) => {
		if (!prev[curr[field]]) {
			prev[curr[field]] = curr
		}

		return prev
	}, {})

	return Object.values(arr)
}


// 计算今天
export const getToday = () => {
    let now = new Date()
    let year = now.getFullYear()
    let month = now.getMonth() + 1
    let day = now.getDate()
    let hour = 0
    let minute = 0
    let second = 0
    let date = year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second

    return date
}

// 获取当前系统时间
// type：true 时分秒，false 年月日时分秒
// dateObj 指定的日期对象
export const getSystemDate = (type, dateObj) => {
    let now = dateObj ? dateObj : new Date()
    let year = now.getFullYear()
    let month = now.getMonth() + 1
    let day = now.getDate()
    let hour = now.getHours()
    let minute = now.getMinutes()
    let second = now.getSeconds()

    month = month > 9 ? month : '0' + month
    day = day > 9 ? day : '0' + day
    hour = hour > 9 ? hour : '0' + hour
    minute = minute > 9 ? minute : '0' + minute
    second = second > 9 ? second : '0' + second

    let date = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
    
    return type ? (hour + ':' + minute + ':' + second) : date
}

// 将时间字符串转换为指定格式的方法
export const formatDateString = (dateString) => {
    // 创建日期对象
    let dateObj = new Date(dateString);

    // 获取年月日时分秒
    let year = dateObj.getFullYear();
    let month = ("0" + (dateObj.getMonth() + 1)).slice(-2); // 月份是从0开始的，需要加1
    let day = ("0" + dateObj.getDate()).slice(-2);
    let hours = ("0" + dateObj.getHours()).slice(-2);
    let minutes = ("0" + dateObj.getMinutes()).slice(-2);
    let seconds = ("0" + dateObj.getSeconds()).slice(-2);

    // 拼接成目标格式
    let formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;

    return formattedDate;
}

 
// 将数字转换为大写金额
export const changeToChinese = (Num) => {
	//判断如果传递进来的不是字符的话转换为字符
	if (typeof Num == "number") {
		Num = new String(Num);
	};
	Num = Num.replace(/,/g, "") //替换tomoney()中的“,”
	Num = Num.replace(/ /g, "") //替换tomoney()中的空格
	Num = Num.replace(/￥/g, "") //替换掉可能出现的￥字符
	if (isNaN(Num)) { //验证输入的字符是否为数字
		//alert("请检查小写金额是否正确");
		return "";
	};
	//字符处理完毕后开始转换，采用前后两部分分别转换
	var part = String(Num).split(".");
	var newchar = "";
	//小数点前进行转化
	for (var i = part[0].length - 1; i >= 0; i--) {
		if (part[0].length > 10) {
			return "";
			//若数量超过拾亿单位，提示
		}
		var tmpnewchar = ""
		var perchar = part[0].charAt(i);
		switch (perchar) {
			case "0":
				tmpnewchar = "零" + tmpnewchar;
				break;
			case "1":
				tmpnewchar = "壹" + tmpnewchar;
				break;
			case "2":
				tmpnewchar = "贰" + tmpnewchar;
				break;
			case "3":
				tmpnewchar = "叁" + tmpnewchar;
				break;
			case "4":
				tmpnewchar = "肆" + tmpnewchar;
				break;
			case "5":
				tmpnewchar = "伍" + tmpnewchar;
				break;
			case "6":
				tmpnewchar = "陆" + tmpnewchar;
				break;
			case "7":
				tmpnewchar = "柒" + tmpnewchar;
				break;
			case "8":
				tmpnewchar = "捌" + tmpnewchar;
				break;
			case "9":
				tmpnewchar = "玖" + tmpnewchar;
				break;
		}
		switch (part[0].length - i - 1) {
			case 0:
				tmpnewchar = tmpnewchar + "元";
				break;
			case 1:
				if (perchar != 0) tmpnewchar = tmpnewchar + "拾";
				break;
			case 2:
				if (perchar != 0) tmpnewchar = tmpnewchar + "佰";
				break;
			case 3:
				if (perchar != 0) tmpnewchar = tmpnewchar + "仟";
				break;
			case 4:
				tmpnewchar = tmpnewchar + "万";
				break;
			case 5:
				if (perchar != 0) tmpnewchar = tmpnewchar + "拾";
				break;
			case 6:
				if (perchar != 0) tmpnewchar = tmpnewchar + "佰";
				break;
			case 7:
				if (perchar != 0) tmpnewchar = tmpnewchar + "仟";
				break;
			case 8:
				tmpnewchar = tmpnewchar + "亿";
				break;
			case 9:
				tmpnewchar = tmpnewchar + "拾";
				break;
		}
		var newchar = tmpnewchar + newchar;
	}
	//小数点之后进行转化
	if (Num.indexOf(".") != -1) {
		if (part[1].length > 2) {
			// alert("小数点之后只能保留两位,系统将自动截断");
			part[1] = part[1].substr(0, 2)
		}
		for (i = 0; i < part[1].length; i++) {
			tmpnewchar = ""
			perchar = part[1].charAt(i)
			switch (perchar) {
				case "0":
					tmpnewchar = "零" + tmpnewchar;
					break;
				case "1":
					tmpnewchar = "壹" + tmpnewchar;
					break;
				case "2":
					tmpnewchar = "贰" + tmpnewchar;
					break;
				case "3":
					tmpnewchar = "叁" + tmpnewchar;
					break;
				case "4":
					tmpnewchar = "肆" + tmpnewchar;
					break;
				case "5":
					tmpnewchar = "伍" + tmpnewchar;
					break;
				case "6":
					tmpnewchar = "陆" + tmpnewchar;
					break;
				case "7":
					tmpnewchar = "柒" + tmpnewchar;
					break;
				case "8":
					tmpnewchar = "捌" + tmpnewchar;
					break;
				case "9":
					tmpnewchar = "玖" + tmpnewchar;
					break;
			}
			if (i == 0) tmpnewchar = tmpnewchar + "角";
			if (i == 1) tmpnewchar = tmpnewchar + "分";
			newchar = newchar + tmpnewchar;
		}
	}
	//替换所有无用汉字
	while (newchar.search("零零") != -1)
		newchar = newchar.replace("零零", "零");
	newchar = newchar.replace("零亿", "亿");
	newchar = newchar.replace("亿万", "亿");
	newchar = newchar.replace("零万", "万");
	newchar = newchar.replace("零元", "元");
	newchar = newchar.replace("零角", "");
	newchar = newchar.replace("零分", "");
	if (newchar.charAt(newchar.length - 1) == "元") {
		newchar = newchar + "整"
	}
	return newchar;
}

// 数组反向递归父元素，field：字段名，必须具有唯一性
export const getParentNodes = (tree, field) => {
	// 遍历树节点
	for (let node of tree) {
		// 如果当前节点就是目标节点的父节点，直接返回当前节点内容
		if (node.children && node.children.some(item => item[field] === field)) {
			return item
		}

		// 否则继续遍历当前节点的子节点
		if (node.children) {
			const item = getParentNodes(node.children, field)

			if (item !== null) {
				return item
			}
		}
	}

	// 如果没有找到父节点，返回 null
	return null
}

// 将路由转换为懒加载方式
export const loadView = (view) => {
    if (process.env.NODE_ENV === 'development') {
        return (resolve) => require([`@/views/${view}`], resolve)
    } else {
        // 使用 import 实现生产环境的路由懒加载
        return () => import(`@/views/${view}`)
    }
}

// 根据页面路由匹配权限路由对应的权限列表
export const mateMenuInfo = (data, path) => {
	if (data && data.length > 0) {
		for (let i = 0; i < data.length; i++) {
			if (data[i].component === path) {
				return data[i]
			}

			if (data[i].children && data[i].children.length > 0) {
				return mateMenuInfo(data[i].children, path)
			}
		}
	}
}

// 根据权限展示操作按钮（data：按钮集合）
export const getPermsBtns = (data) => {
	let arr = data.filter(item => {
		if (item.permission === null || item.permission === '' && item.permission !== undefined || checkUserPermission(item.permission)) {
			return item
		}
	})

	return arr
}

// 判断当前用户是否具有操作权限，permission：权限字符，超管权限："*:*:*"
export const checkUserPermission = (permission) => {
	let isPermission = false

	if (store.state.user.userPermissions.indexOf(permission) !== -1 || store.state.user.userPermissions.indexOf("*:*:*") !== -1) {
		// 存在操作权限
		isPermission = true
	}

	return isPermission
}

// 文件流转换
export const blobUrl = (res) => {
	let blob = new Blob([res]); // 返回的文件流数据
	let url = window.URL.createObjectURL(blob); // 将他转化为路径

	return url
}

